﻿using OSDA.ViewModels;
using System;
using System.Collections.ObjectModel;
using System.IO.Ports;
using System.Timers;
using System.Windows.Media;

namespace OSDA.Models
{
    internal class SerialPortModel : MainWindowBase, IDisposable
    {
        public Collection<int> BaudRateItemsSource { get; set; }
        public Collection<int> DataBitsItemsSource { get; set; }
        public Collection<StopBits> StopBitsItemsSource { get; set; }
        public Collection<Parity> ParityItemsSource { get; set; }

        private Timer tmr;
        private bool isOpened = false;

        private string[] _PortItemsSource;
        public string[] PortItemsSource
        {
            get => _PortItemsSource;
            set => SetProperty(ref _PortItemsSource, value);
        }

        #region 串口配置区 - 串口属性
        private string _Port;
        public string Port
        {
            get => _Port;
            set => SetProperty(ref _Port, value);
        }

        private int _BaudRate;
        public int BaudRate
        {
            get => _BaudRate;
            set => SetProperty(ref _BaudRate, value);
        }

        private int _DataBits;
        public int DataBits
        {
            get => _DataBits;
            set => SetProperty(ref _DataBits, value);
        }

        private StopBits _StopBits;
        public StopBits StopBits
        {
            get => _StopBits;
            set => SetProperty(ref _StopBits, value);
        }

        private Parity _Parity;
        public Parity Parity
        {
            get => _Parity;
            set => SetProperty(ref _Parity, value);
        }
        #endregion

        #region 串口配置区 - 打开/关闭
        private Brush _Brush;
        public Brush Brush
        {
            get => _Brush;
            set => SetProperty(ref _Brush, value);
        }

        private string _OpenClose;
        public string OpenClose
        {
            get => _OpenClose;
            set
            {
                if (SetProperty(ref _OpenClose, value))
                {
                    isOpened = !isOpened;
                }
            }
        }
        #endregion

        #region 控件启用状态
        private bool _PortEnable;
        public bool PortEnable
        {
            get => _PortEnable;
            set => SetProperty(ref _PortEnable, value);
        }

        private bool _BaudRateEnable;
        public bool BaudRateEnable
        {
            get => _BaudRateEnable;
            set => SetProperty(ref _BaudRateEnable, value);
        }

        private bool _DataBitsEnable;
        public bool DataBitsEnable
        {
            get => _DataBitsEnable;
            set => SetProperty(ref _DataBitsEnable, value);
        }

        private bool _StopBitsEnable;
        public bool StopBitsEnable
        {
            get => _StopBitsEnable;
            set => SetProperty(ref _StopBitsEnable, value);
        }

        private bool _ParityEnable;
        public bool ParityEnable
        {
            get => _ParityEnable;
            set => SetProperty(ref _ParityEnable, value);
        }
        #endregion

        #region 字符编码选项
        private bool _GBKEnable;
        public bool GBKEnable
        {
            get => _GBKEnable;
            set => SetProperty(ref _GBKEnable, value);
        }

        private bool _ASCIIEnable;
        public bool ASCIIEnable
        {
            get => _ASCIIEnable;
            set => SetProperty(ref _ASCIIEnable, value);
        }

        private bool _UTF8Enable;
        public bool UTF8Enable
        {
            get => _UTF8Enable;
            set => SetProperty(ref _UTF8Enable, value);
        }

        private bool _UTF16Enable;
        public bool UTF16Enable
        {
            get => _UTF16Enable;
            set => SetProperty(ref _UTF16Enable, value);
        }

        private bool _UTF32Enable;
        public bool UTF32Enable
        {
            get => _UTF32Enable;
            set => SetProperty(ref _UTF32Enable, value);
        }
        #endregion

        #region DTR/RTS 设置
        private bool _DtrEnable;
        public bool DtrEnable
        {
            get => _DtrEnable;
            set => SetProperty(ref _DtrEnable, value);
        }

        private bool _RtsEnable;
        public bool RtsEnable
        {
            get => _RtsEnable;
            set => SetProperty(ref _RtsEnable, value);
        }
        #endregion

        #region 流控制设置
        private bool _NoneEnable;
        public bool NoneEnable
        {
            get => _NoneEnable;
            set => SetProperty(ref _NoneEnable, value);
        }

        private bool _RequestToSendEnable;
        public bool RequestToSendEnable
        {
            get => _RequestToSendEnable;
            set => SetProperty(ref _RequestToSendEnable, value);
        }

        private bool _XOnXOffEnable;
        public bool XOnXOffEnable
        {
            get => _XOnXOffEnable;
            set => SetProperty(ref _XOnXOffEnable, value);
        }

        private bool _RequestToSendXOnXOffEnable;
        public bool RequestToSendXOnXOffEnable
        {
            get => _RequestToSendXOnXOffEnable;
            set => SetProperty(ref _RequestToSendXOnXOffEnable, value);
        }
        #endregion

        #region 信号指示灯
        private Brush _DcdBrush;
        public Brush DcdBrush
        {
            get => _DcdBrush;
            set => SetProperty(ref _DcdBrush, value);
        }

        private Brush _CtsBrush;
        public Brush CtsBrush
        {
            get => _CtsBrush;
            set => SetProperty(ref _CtsBrush, value);
        }

        private Brush _DsrBrush;
        public Brush DsrBrush
        {
            get => _DsrBrush;
            set => SetProperty(ref _DsrBrush, value);
        }
        #endregion

        private void Tmr_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (isOpened) return;

            try
            {
                PortItemsSource = SerialPort.GetPortNames();
            }
            catch
            {
                // 忽略异常或记录日志
            }
        }

        public void SerialPortDataContext()
        {
            if (tmr == null)
            {
                try
                {
                    PortItemsSource = SerialPort.GetPortNames();
                }
                catch
                {
                    PortItemsSource = [];
                }

                tmr = new Timer(3 * 1000);
                tmr.Elapsed -= Tmr_Elapsed;
                tmr.Elapsed += Tmr_Elapsed;
                tmr.Start();
            }

            BaudRateItemsSource = [.. CollectionHelpers.DefaultBaudRates];
            DataBitsItemsSource = [.. CollectionHelpers.DefaultDataBits];
            StopBitsItemsSource = [.. CollectionHelpers.DefaultStopBits];
            ParityItemsSource = [.. CollectionHelpers.DefaultParity];

            BaudRate = 115200;
            DataBits = 8;
            StopBits = StopBits.One;
            Parity = Parity.None;

            Brush = Brushes.Red;
            OpenClose = "打开串口";
            isOpened = false;

            SetAllPortSettingsEnabled(true);

            /* 字节编码 */
            ASCIIEnable = false;
            UTF8Enable = true;
            UTF16Enable = false;
            UTF32Enable = false;

            DtrEnable = false;
            RtsEnable = false;

            /* 流控制 */
            NoneEnable = true;
            RequestToSendEnable = false;
            XOnXOffEnable = false;
            RequestToSendXOnXOffEnable = false;

            /* 信号状态 */
            DcdBrush = Brushes.Black;
            CtsBrush = Brushes.Black;
            DsrBrush = Brushes.Black;
        }

        private void SetAllPortSettingsEnabled(bool enabled)
        {
            PortEnable = enabled;
            BaudRateEnable = enabled;
            DataBitsEnable = enabled;
            StopBitsEnable = enabled;
            ParityEnable = enabled;
        }

        public void Dispose()
        {
            if (tmr != null)
            {
                tmr.Stop();
                tmr.Elapsed -= Tmr_Elapsed;
                tmr.Dispose();
                tmr = null;
            }
        }
    }

    // 可选：将常用集合提取到静态类中以避免重复初始化
    public static class CollectionHelpers
    {
        public static readonly int[] DefaultBaudRates =
        [
            1200, 2400, 4800, 7200, 9600, 14400, 19200, 28800,
            38400, 57600, 115200, 128000, 153600, 230400, 256000
        ];

        public static readonly int[] DefaultDataBits = [5, 6, 7, 8];

        public static readonly StopBits[] DefaultStopBits =
        [
            StopBits.One, StopBits.Two, StopBits.OnePointFive
        ];

        public static readonly Parity[] DefaultParity =
        [
            Parity.None, Parity.Odd, Parity.Even, Parity.Mark, Parity.Space
        ];
    }
}